﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Drawing;
using System.Drawing.Drawing2D;
using Microsoft.SharePoint;
using System.Web;
using Microsoft.SharePoint.Utilities;
using SPPivotViewer.Utility;

namespace SPPivotViewer.HttpHandler.Internal.ImageProviders
{
    internal class DocumentImage : ImageBase
    {
        private string _strPath = "";
        SPListItem li = null;
        private string m_title;
        private Dictionary<string, string> m_metadata;
        bool _bFeatureCheck = false;
        bool _bThumbExtentender = false;
        bool _bOfficeWebApps = false;
        public DocumentImage(Uri Path, string title, Dictionary<string, string> metadata)
        {
            this._strPath=HttpUtility.UrlEncode(Path.AbsoluteUri);
            this.m_title = title;
            this.m_metadata = metadata;
            using (SPWeb web = SPContext.Current.Site.RootWeb)
            {
                string returnURL = HttpUtility.UrlDecode(_strPath);
                using (SPSite site = new SPSite(returnURL))
                {
                    using (SPWeb myWeb = site.OpenWeb())
                    {
                        try
                        {
                            li = myWeb.GetListItem(returnURL);
                        }
                        catch
                        { }
                    }
                }
            }
        }
        private void getFeatureActive(out bool bOfficeWebApps, out bool bThumbExtentender)
        {
            if (_bFeatureCheck)
            {
                bThumbExtentender = _bThumbExtentender;
                bOfficeWebApps=_bOfficeWebApps;
                return;
            }
            SPSite currentSite = SPContext.Current.Site;
            SPFeatureCollection sfc = currentSite.Features;
            bThumbExtentender = false;
            bOfficeWebApps = false;
            foreach (SPFeature feature in sfc)
            {
                if ((feature.Definition.Id == new Guid("0C504A5C-BCEA-4376-B05E-CBCA5CED7B4F")) && (feature.Definition.Scope == SPFeatureScope.Site))
                {
                    bOfficeWebApps=true;
                }
                if ((feature.Definition.Id == new Guid("020c3d9e-88ab-4c9e-899f-8de97927c751")) && (feature.Definition.Scope == SPFeatureScope.Site))
                {
                    bThumbExtentender=true;
                }
            }
            _bFeatureCheck = true;
        }

        
        protected override System.Drawing.Image[] MakeImage()
        {
            if (li == null)
            {
                DynamicImage dynImg = new DynamicImage(m_title, m_metadata);
                byte[][] abytImage = dynImg.ImageData;
                List<Image> lstImg = new List<Image>();
                foreach (byte[] b in abytImage)
                {
                    MemoryStream ms = new MemoryStream(b);
                    Image img = Image.FromStream(ms);
                    lstImg.Add(img);
                }

                return lstImg.ToArray(); ;
            }
            System.Drawing.Image[] imgReturn = null;
            bool bOfficeWebApps;
            bool bThumbExt;
            getFeatureActive(out bOfficeWebApps, out bThumbExt);
            string extension = getFileExtension(_strPath);
            bool _bthumbs=false;
            if (bool.TryParse(PV4SPSettings.GetValue(li.Web,PV4SPSettings.cstThumbs), out _bthumbs) && !_bthumbs)
            {    
                return GenerateGenericThumbnail(_strPath); 
            }
            if (bOfficeWebApps && extension.StartsWith("doc"))
                imgReturn = GenerateDocThumbnail(_strPath, extension);
            else if (bOfficeWebApps && extension.StartsWith("ppt"))
                imgReturn = GeneratePptThumbnail(_strPath);
            else if(bThumbExt==true && extension.Equals("xps"))
                 imgReturn = GenerateXpsThumbnail(_strPath);
            else
                imgReturn = GenerateGenericThumbnail(_strPath);


            return imgReturn;
        }

        private Image[] GenerateXpsThumbnail(string _strPath)
        {
            List<Image> imgReturn = new List<Image>();
            string strDocgenerate = li.Web.Url + "/_layouts/SPThumbnailExtender/MobileXPSHandler.ashx?xps=" + _strPath;
              int  imageWidth = 210;
              int  imageHeight = 297;

            string dimension = string.Format("&n=0&width={0}&height={1}", imageWidth, imageHeight);

            Uri uri = new Uri(strDocgenerate + dimension, UriKind.Absolute);
            using (Image imgResult = GetImageFromURI(uri))
            {
                FillLayers(imgResult, m_title, m_metadata, ref imgReturn);
            }
            return imgReturn.ToArray();
        }

        private System.Drawing.Image[] GenerateDocThumbnail(string _strPath, string extension)
        {
            try
            {
                List<Image> imgReturn = new List<Image>();
                string strDocgenerate = li.Web.Url + "/_layouts/MobileDocHandler.ashx?doc=" + _strPath;
                strDocgenerate += extension == "doc" ? "&type=thumbnail" : "";
                HttpWebRequest requestDocHandler = (HttpWebRequest)HttpWebRequest.Create(strDocgenerate);
                requestDocHandler.Credentials = CredentialCache.DefaultCredentials;
                HttpWebResponse responseDocHandler = (HttpWebResponse)requestDocHandler.GetResponse();
                string strUrlImage;
                using (StreamReader streamReaderDocHandler = new StreamReader(responseDocHandler.GetResponseStream()))
                {
                    string resultStringDoc = streamReaderDocHandler.ReadToEnd();
                    XDocument xdocDoc = XDocument.Parse(resultStringDoc);
                    strUrlImage = xdocDoc.Element("mobileDoc").Element("pageImage").Attribute("url").Value;
                    if (extension == "doc")
                    {
                        string strUrl1 = li.Web.Url + "/_layouts/" + strUrlImage + "&n=t1.jpg&width=210&height=297";
                        Uri uri1 = new Uri(strUrl1, UriKind.Absolute);
                        using (Image imgResult = GetImageFromURI(uri1))
                        {
                            FillLayers(imgResult, m_title, m_metadata, ref imgReturn);
                        }
                    }
                    else
                    {
                        HttpWebRequest requestDocXML = (HttpWebRequest)HttpWebRequest.Create(li.Web.Url + "/_layouts/" + strUrlImage + "&n=p_1_10.xml");
                        requestDocXML.Credentials = CredentialCache.DefaultCredentials;
                        HttpWebResponse responseDocXml = (HttpWebResponse)requestDocXML.GetResponse();
                        using (StreamReader streamReaderImage = new StreamReader(responseDocXml.GetResponseStream()))
                        {
                            string resultStringImage = streamReaderImage.ReadToEnd();
                            XDocument xdocImg = XDocument.Parse(resultStringImage);
                            string firstPageID = xdocImg.Element("Pages").Element("Page").Element("P").Element("L").Element("LT").Attribute("p").Value;

                            int PageID = int.Parse(firstPageID);
                            string strUrl1 = li.Web.Url + "/_layouts/" + strUrlImage + "&n=p" + PageID.ToString() + ".img&width=210&height=297&fmt=jpeg";
                            Uri uri1 = new Uri(strUrl1, UriKind.Absolute);
                            using (Image imgResult = GetImageFromURI(uri1))
                            {
                                FillLayers(imgResult, m_title, m_metadata, ref imgReturn);
                            }
                        }
                    }
                }
                return imgReturn.ToArray();
            }
            catch
            {
                return GenerateGenericThumbnail(_strPath);
            }
        }

        private System.Drawing.Image GetImageFromURI(Uri url)
        {
            System.Drawing.Image imgTemp;
            using (System.Net.WebClient c = new System.Net.WebClient())
            {
                c.Credentials = CredentialCache.DefaultCredentials;
                Stream s = c.OpenRead(url);
                imgTemp = System.Drawing.Image.FromStream(s);
                s.Close();
            }
            return imgTemp;
        }

        private System.Drawing.Image[] GeneratePptThumbnail(string _strPath)
        {
            try
            {
                List<Image> imgReturn = new List<Image>();
                HttpWebRequest requestPPT = (HttpWebRequest)HttpWebRequest.Create(li.Web.Url + "/_layouts/MobilePresentation.ashx?presentationId=" + _strPath);
                requestPPT.Credentials = CredentialCache.DefaultCredentials;
                HttpWebResponse responsePPT = (HttpWebResponse)requestPPT.GetResponse();
                using (StreamReader streamReader1 = new StreamReader(responsePPT.GetResponseStream()))
                {
                    string resultString = streamReader1.ReadToEnd();
                    XDocument xdoc = XDocument.Parse(resultString);

                    string strImageUrl = xdoc.Element(XName.Get("mobilePres", "http://schemas.microsoft.com/server/powerpoint/2009/mobile")).Element(XName.Get("slideImage", "http://schemas.microsoft.com/server/powerpoint/2009/mobile")).Attribute("url").Value;

                    string strImageID = xdoc.Element(XName.Get("mobilePres", "http://schemas.microsoft.com/server/powerpoint/2009/mobile")).Element(XName.Get("pres", "http://schemas.microsoft.com/server/powerpoint/2009/mobile")).Element(XName.Get("sldLst", "http://schemas.microsoft.com/server/powerpoint/2009/mobile")).Element(XName.Get("sld", "http://schemas.microsoft.com/server/powerpoint/2009/mobile")).Attribute("sldImg").Value;
                    string strUrl = li.Web.Url + "/_layouts/" + strImageUrl + "&imageId=" + strImageID + "&width=320&height=240&format=jpeg";
                    Uri uri = new Uri(strUrl, UriKind.Absolute);
                    using (Image imgResult = GetImageFromURI(uri))
                    {
                        FillLayers(imgResult, m_title, m_metadata, ref imgReturn);
                    }
                }
                return imgReturn.ToArray();
            }
            catch
            {
                return GenerateGenericThumbnail(_strPath);
            }

        }

        private System.Drawing.Image[] GenerateGenericThumbnail(string _strPath)
        {

            return DrawBitmap(320, 240);

        }
        private string getFileExtension(string url)
        {
            string strFileExt = "";
            string strFileUrl = url;
            strFileExt = strFileUrl.Substring(strFileUrl.LastIndexOf('.') + 1);
            return strFileExt.ToLower().Trim();
        }
        private Image[] DrawBitmap(int width, int height)
        {
            Bitmap bitmap = new Bitmap(width, height);
            try
            {
                using (Graphics graph = Graphics.FromImage(bitmap))
                {
                    Rectangle rect = new Rectangle(0, 0, width - 1, height - 1);
                    DrawIconDoc(graph, rect);
                }
            }
            catch
            {
                bitmap.Dispose();
                bitmap = null;
            }
            List<Image> imgReturn = new List<Image>();
            FillLayers(bitmap, m_title, m_metadata, ref imgReturn);
            bitmap.Dispose();
            bitmap = null;
            return imgReturn.ToArray();
        }

        private void DrawImage(Graphics g, Rectangle rect, string ImagePath)
        {
            HttpWebRequest requestImg = (HttpWebRequest)HttpWebRequest.Create(ImagePath);
            requestImg.Credentials = CredentialCache.DefaultCredentials;
            HttpWebResponse responseImg = (HttpWebResponse)requestImg.GetResponse();
            Stream strImg = responseImg.GetResponseStream();
            Image img = Image.FromStream(strImg);
            strImg.Close();
            strImg.Dispose();
            strImg = null;
            float nPercent = 0;
            float nPercentH = 0;
            float nPercentW = 0;

            nPercentW = ((float)(rect.Width / 2) / (float)img.Width);
            nPercentH = ((float)(rect.Height / 2) / (float)img.Height);

            if (nPercentH < nPercentW)
                nPercent = nPercentH;
            else
                nPercent = nPercentW;

            int destWidth = (int)(img.Width * nPercent);
            int destHeight = (int)(img.Height * nPercent);
            g.DrawImage(img, (rect.Width - destWidth) / 2, (rect.Height - destHeight) / 2, destWidth, destHeight);
            img.Dispose();
            img = null;
        }
        private void DrawIconDoc(Graphics g, Rectangle rect)
        {
            string strIcon = SPUtility.MapToIcon(SPContext.Current.Web, _strPath, string.Empty);
            if (li.ContentTypeId.IsChildOf(new SPContentTypeId("0x0120D520")))
                strIcon = "docset_welcomepage_big.png";

            string strIconPath = SPContext.Current.Web.Url + "/_layouts/images/" + strIcon;
            DrawImage(g, rect, strIconPath);
        }

        // Private Fields
        //======================================================================

        static readonly Size imageSize_c = new Size(256, 256); //Default size is chosen so it fits exactly to a collection tile.

    }
}
